package com.codeyang.mocktest2.mockit;


import com.codeyang.mocktest2.entity.TUser;
import com.codeyang.mocktest2.mapper.TUserMapper;
import com.codeyang.mocktest2.service.TUserService;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.MockitoAnnotations;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.mock.mockito.SpyBean;
import org.springframework.test.context.junit4.SpringRunner;

import java.util.List;

/**
 * 描述:
 * 21 RunWith 是启动什么上下文
 * 1使用SpringRunner 就可以得到Spring的容器的上下文
 * 2SpringTest 是走SpringTest的一套流程
 *
 * @author shengyang5
 * @version 2021/7/22 15:29
 */
@RunWith(SpringRunner.class)
@SpringBootTest
public class SpyBeanStudy01 {

    /**
     * 如果要使用@Mock @Spy 原生注解需要前置启动
     */
    @Before
    public void Before() throws Exception {
        MockitoAnnotations.initMocks(this);
    }


    /**
     * @SpyBean |
     * 1 继承了@Spy的特性 方法调用没有打桩走真实第哦啊有
     * 2 比@Spy更强可以兼容普通的Bean对象创建的对象 可以调用非代理对象的真实方法
     * （测试对于JDK的动态代理对象兼容不行，CGLIB的没有测试）
     * 3 对于Mybatis等动态代理的对象 要支持必须要引入mockito-inline 2.7 以上
     * 4 @SpyBean 比 @Spy 更智能，可以自动主力类其他资源的依赖关系，并自动加入
     * 5 @Spy 只支持到具体的类 @SpyBean可以支持接口-可以把spring的bean对象自动 spy
     */
    // @Spy  // 如果是@Spy 就会报错，因为其 它无法将 userService 里的 TUserMapper处理
    // private TUserServiceImpl userService;
    @SpyBean
    private TUserService userService;



    @Test
    public void userServiceQueryAll() throws Exception {
        List<TUser> tUsers = userService.queryAll();
        System.out.println(tUsers);
    }

    /**
     * 对于动态代理对象无法直接mock 需要引入第三方jar mock-inline
     */
    @SpyBean
    private TUserMapper userMapper;

    @Test
    public void userMapperQueryAll() throws Exception {
        List<TUser> tUsers = userMapper.selectAll();
        System.out.println(tUsers);
    }


}
